home *** CD-ROM | disk | FTP | other *** search
/ Best Tools for JAVA / Best Tools for JAVA.iso / POSTSCPT / GSVIEW / SRC / OS2SETUP.C < prev    next >
Encoding:
C/C++ Source or Header  |  1996-01-10  |  17.3 KB  |  686 lines

  1. /* Copyright (C) 1993-1996, Russell Lang.  All rights reserved.
  2.   
  3.   This file is part of GSview.
  4.   
  5.   This program is distributed with NO WARRANTY OF ANY KIND.  No author
  6.   or distributor accepts any responsibility for the consequences of using it,
  7.   or for whether it serves any particular purpose or works at all, unless he
  8.   or she says so in writing.  Refer to the GSview Free Public Licence 
  9.   (the "Licence") for full details.
  10.   
  11.   Every copy of GSview must include a copy of the Licence, normally in a 
  12.   plain ASCII text file named LICENCE.  The Licence grants you the right 
  13.   to copy, modify and redistribute GSview, but only under certain conditions 
  14.   described in the Licence.  Among other things, the Licence requires that 
  15.   the copyright notice and this notice be preserved on all copies.
  16. */
  17.  
  18. /* os2setup.c */
  19. /* OS/2 installation program for GSview and Ghostscript */
  20.  
  21. #define INCL_DOS
  22. #define INCL_WIN
  23. #define INCL_GPI
  24. #define INCL_DOSERRORS
  25. #include <os2.h>
  26. #include <stdio.h>
  27. #include <stdlib.h>
  28. #include <string.h>
  29. #include <io.h>
  30.  
  31. #define MAXSTR 256
  32. #define GVFAR
  33.  
  34. #include "setup.h"
  35. #include "gvcprf.h"
  36. #include "gvcrc.h"
  37.  
  38. #define BASEDIR "\\gs3.53"
  39. #define UNZIPEXE "os2unzip.exe"
  40. #define GSVIEWZIP "gsview.zip"
  41. #define GSINIZIP  "gs353ini.zip"
  42. #define GSOS2ZIP  "gs353os2.zip"
  43. #define GSFNTZIP  "gs353fn1.zip"
  44. #define EMXZIP    "emxrt.zip"
  45.  
  46. MRESULT EXPENTRY GeneralDlgProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2);
  47. MRESULT EXPENTRY InputDlgProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2);
  48.  
  49. char workdir[MAXSTR];
  50. char bootdrive[MAXSTR];
  51. char destdir[MAXSTR];
  52. char unzipname[MAXSTR];
  53. HAB hab;
  54. HWND hwnd_dlg;
  55. char get_string_answer[MAXSTR];
  56. char szAppName[]="GSview Install";
  57. char szExePath[MAXSTR];
  58. char error_message[MAXSTR];
  59. char no_error[] = "";
  60. int emx;
  61. int use_os2_fonts;
  62.  
  63. HQUEUE        term_queue;    /* termination queue for child sessions */
  64. char         term_queue_name[MAXSTR];
  65. TID         term_tid;
  66. VOID APIENTRY    term_thread(ULONG unused);
  67.  
  68. int
  69. dialog(int resource, PFNWP dlgproc)
  70. {
  71. int flag;
  72.     flag = WinDlgBox(HWND_DESKTOP, HWND_DESKTOP, dlgproc, 0, resource, 0);
  73.     return flag;
  74. }
  75.  
  76. int message_box(char *str, int icon)
  77. {
  78.     return WinMessageBox(HWND_DESKTOP, HWND_DESKTOP,
  79.                  str, szAppName, 0, icon);
  80. }
  81.  
  82. int copyfile(char *dname, char *sname)
  83. {
  84. FILE *dfile, *sfile;
  85. char *buffer;
  86. int count;
  87. #define COPY_BUF_SIZE 16384
  88.     sfile = fopen(sname, "rb");
  89.     if (sfile == (FILE *)NULL) {
  90.     sprintf(error_message, "Can't open %s for reading", sname);
  91.     return 1;
  92.     }
  93.     dfile = fopen(dname, "wb");
  94.     if (dfile == (FILE *)NULL) {
  95.     sprintf(error_message, "Can't open %s for writing", dname);
  96.     fclose(sfile);
  97.     return 1;
  98.     }
  99.     if ( (buffer = malloc(COPY_BUF_SIZE)) == (char *)NULL ) {
  100.     fclose(sfile);
  101.     fclose(dfile);
  102.     sprintf(error_message, "Can't allocate memory for copy buffer");
  103.     return 1;
  104.     }
  105.  
  106.     while ( (count = fread(buffer, 1, COPY_BUF_SIZE, sfile)) != 0 )
  107.     fwrite(buffer, 1, count, dfile);
  108.  
  109.     free(buffer);
  110.     fclose(dfile);
  111.     fclose(sfile);
  112.     return 0;
  113. }
  114.  
  115. int
  116. intro(void)
  117. {
  118.     /* Introduction */
  119.     if (dialog(IDD_INTRO, GeneralDlgProc) != DID_OK) {
  120.     strcpy(error_message, no_error);
  121.     return 1;
  122.     }
  123.  
  124.     /* Copyright */
  125.     if (dialog(IDD_COPYRIGHT, GeneralDlgProc) != DID_OK) {
  126.     strcpy(error_message, no_error);
  127.     return 1;
  128.     }
  129.  
  130.     return 0; /* success */
  131. }
  132.  
  133. int
  134. getdest(void)
  135. {
  136. int valid;
  137. int i;
  138.     valid = 0;
  139.     while (!valid) {
  140.         /* Destination directory */
  141.         strcpy(get_string_answer, bootdrive);
  142.         strcat(get_string_answer,"\\"); 
  143.         if (dialog(IDD_DIR, InputDlgProc) != DID_OK) {
  144.         strcpy(error_message, no_error);
  145.         return 1;
  146.     }
  147.         strcpy(destdir, get_string_answer);
  148.         if (_chdir2(destdir))
  149.         message_box( "Directory does not exist.  Please enter a directory name that does exist.",
  150.          MB_MOVEABLE | MB_OK);
  151.     else
  152.         valid = 1;
  153.     _chdir2(workdir);
  154.     }
  155.     /* remove trailing \ from destination directory */
  156.     i = strlen(destdir) - 1;
  157.     if ( (i >= 0) && (destdir[i] == '\\') )
  158.     destdir[i] = '\0';
  159.     return 0;
  160. }
  161.  
  162. int
  163. init(void)
  164. {
  165.     char buf[256];
  166.     char *tail, *env;
  167.     APIRET rc = 0;
  168.  
  169.     PTIB pptib;
  170.     PPIB pppib;
  171.     HMODULE hmodule;
  172.  
  173.     /* get path to EXE */
  174.     if ( (rc = DosGetInfoBlocks(&pptib, &pppib)) != 0 ) {
  175.     sprintf(error_message, "DosGetInfoBlocks rc=%d", rc);
  176.     return rc;
  177.     }
  178.  
  179.     /* get path to EXE */
  180.     if ( (rc = DosQueryModuleName(pppib->pib_hmte, sizeof(szExePath), szExePath)) != 0 ) {
  181.     sprintf(error_message, "DosQueryModuleName rc=%d", rc);
  182.     return rc;
  183.     }
  184.     if ((tail = strrchr(szExePath,'\\')) != (PCHAR)NULL) {
  185.     tail++;
  186.     *tail = '\0';
  187.     }
  188.  
  189.     /* create termination queue */
  190.     sprintf(term_queue_name, "\\QUEUES\\TERM_GSINSTALL_%u", pppib->pib_ulpid);
  191.     if ( (rc = DosCreateQueue(&term_queue, QUE_FIFO, term_queue_name)) != 0 ) {
  192.     sprintf(error_message, "DosCreateQueue rc=%d", rc);
  193.     return rc;
  194.     }
  195.     /* start termination queue thread */
  196.     if ( (rc = DosCreateThread(&term_tid, term_thread, 0, 0, 8192)) != 0 ) {
  197.     sprintf(error_message, "DosCreateThread rc=%d", rc);
  198.         return rc;
  199.     }
  200.  
  201.     /* Inspect system, get boot drive */
  202.     getcwd(workdir, sizeof(workdir));    /* remember the working directory */
  203.     strcpy(bootdrive, getenv("USER_INI"));
  204.     bootdrive[2] = '\0';
  205.     if ( !(rc = DosLoadModule(buf, sizeof(buf), "EMX", &hmodule)) ) {
  206.     emx = TRUE;
  207.     DosFreeModule(hmodule);
  208.     }
  209.  
  210.     /* don't bother checking for OS/2 fonts */
  211.     /* since all versions of OS/2 should have 13 base fonts */
  212.     
  213.     return 0;
  214. }
  215.  
  216. int
  217. cleanup(void)
  218. {
  219.     /* close queue to make termination thread exit */
  220.     if (term_queue)
  221.         DosCloseQueue(term_queue);
  222.     if (term_tid)
  223.         DosKillThread(term_tid);
  224.     return 0;
  225. }
  226.  
  227.  
  228. int
  229. unzip(char *filename, char *destination)
  230. {
  231.     /* start unzip session */  
  232.     STARTDATA sdata;
  233.     APIRET rc;
  234.     char fullname[256];
  235.     char arg[256];
  236.     PTIB pptib;
  237.     PPIB pppib;
  238.     ULONG session_id; 
  239.     PID process_id;
  240.     FILE *f;
  241.     int file_exists = 0;
  242.  
  243.     /* prompt for disk to be installed */
  244.     strcpy(fullname, szExePath);
  245.     strcat(fullname, filename);
  246.     while (!file_exists) {
  247.         if ( (f = fopen(fullname, "r")) == (FILE *)NULL ) {
  248.         char buf[256];
  249.         sprintf(buf, "Insert disk containing %s", fullname);
  250.         strcpy(get_string_answer, fullname);
  251.         if (dialog(IDD_FILE, InputDlgProc) != DID_OK) {
  252.         strcpy(error_message, no_error);
  253.         return 1;
  254.         }
  255.         strcpy(fullname, get_string_answer);
  256.     }
  257.     else {
  258.         file_exists = TRUE;
  259.         fclose(f);
  260.     }
  261.     }
  262.  
  263.     if (DosGetInfoBlocks(&pptib, &pppib)) {
  264.     sprintf(error_message, "DosGetInfoBlocks rc=%d", rc);
  265.     return 1;
  266.     }
  267.  
  268.     /* set up unzip arguments */
  269.     sprintf(arg, "-o %s -d %s%s", fullname, destination,
  270.     (strlen(destination) == 2) ? "\\" : "");
  271.  
  272.     /* because new program is a different EXE type, 
  273.      * we must use start session not DosExecPgm() */
  274.     sdata.Length = sizeof(sdata);
  275.     sdata.Related = SSF_RELATED_CHILD;    /* to be a child  */
  276.     sdata.FgBg = SSF_FGBG_BACK;        /* start in background */
  277.     sdata.TraceOpt = 0;
  278.     sdata.PgmTitle = unzipname;
  279.     sdata.PgmName = unzipname;
  280.     sdata.PgmInputs = arg;
  281.     sdata.TermQ = term_queue_name;
  282.     sdata.Environment = pppib->pib_pchenv;    /* use Parent's environment */
  283.     /* with pipe needs to inherit redirected stdin */
  284.     sdata.InheritOpt = 0;
  285.     sdata.SessionType = SSF_TYPE_DEFAULT;        /* default is text */
  286.     sdata.IconFile = NULL;
  287.     sdata.PgmHandle = 0;
  288.     sdata.PgmControl = 0;
  289.     sdata.InitXPos = 0;
  290.     sdata.InitYPos = 0;
  291.     sdata.InitXSize = 0;
  292.     sdata.InitYSize = 0;
  293.     sdata.ObjectBuffer = NULL;
  294.     sdata.ObjectBuffLen = 0;
  295.  
  296.     if ( (rc = DosStartSession(&sdata, &session_id, &process_id)) != 0) {
  297.     if (rc == 2)
  298.         sprintf(error_message, "Can't run %s", unzipname);
  299.     else 
  300.         sprintf(error_message, "DosStartSession rc=%d", rc);
  301.     return rc;
  302.     }
  303.  
  304.     
  305.     /* display cancel dialog */
  306.     if (dialog(IDD_UNZIP, GeneralDlgProc) != DID_OK) {
  307.     strcpy(error_message, "Unzip cancelled");
  308.     return 1;
  309.     }
  310.     /* cancel dialog will be sent a DID_OK by termination queue thread */
  311.     return 0;
  312. }
  313.  
  314. int
  315. update_config(void)
  316. {
  317. FILE *infile, *outfile;
  318. char inname[MAXSTR], outname[MAXSTR];
  319. char line[1024];
  320. char tempname[MAXSTR];
  321. char buf[MAXSTR];
  322. int got_temp = 0;
  323. int changed = 0;
  324. int replace = 0;
  325.     
  326.     strcpy(inname, bootdrive);
  327.     strcat(inname, "\\config.sys");
  328.  
  329.     strcpy(tempname, bootdrive);
  330.     strcat(tempname, "\\GSXXXXXX");
  331.     if (mktemp(tempname) == (char *)NULL) {
  332.     strcpy(error_message, "Can't get temporary filename");
  333.     return 1;
  334.     }
  335.  
  336.     if ( (infile = fopen(inname, "r")) == (FILE *)NULL) {
  337.     sprintf(error_message, "Can't open %s for reading", inname);
  338.     return 1;
  339.     }
  340.     if ( (outfile = fopen(tempname, "w")) == (FILE *)NULL)  {
  341.     sprintf(error_message, "Can't create %s for writing", outname);
  342.     return 1;
  343.     }
  344.     while (fgets(line, sizeof(line), infile)) {
  345.         if (strncmp(line, "LIBPATH=", 8) == 0) {
  346.         if (!emx) {
  347.         sprintf(line+strlen(line)-1, ";%s\\emx\\dll\n", bootdrive);
  348.         changed = TRUE;
  349.         }
  350.     }
  351.         if (strncmp(line, "SET PATH=", 9) == 0) {
  352.         if (!emx) {
  353.         sprintf(line+strlen(line)-1, ";%s\\emx\\bin\n", bootdrive);
  354.         changed = TRUE;
  355.         }
  356.     }
  357.     if (strncmp(line, "SET TEMP=", 9) == 0) {
  358.         got_temp = TRUE;
  359.     }
  360.     fputs(line, outfile);
  361.     }
  362.     if (!got_temp) {
  363.     sprintf(line, "SET TEMP=%s\\\n", bootdrive);
  364.     fputs(line, outfile);
  365.     changed = TRUE;
  366.     }
  367.  
  368.     fclose(outfile);
  369.     fclose(infile);
  370.  
  371.     if (changed) {
  372.     replace = (dialog(IDD_CONFIG, GeneralDlgProc) == DID_OK);
  373.     strcpy(outname, bootdrive);
  374.     strcat(outname, "\\config.gs");
  375.     if ( (outfile = fopen(outname, "r")) != (FILE *)NULL)  {
  376.         fclose(outfile);
  377.         sprintf(buf, "File %s exists.  Overwrite?", outname);
  378.         if (message_box(buf, MB_MOVEABLE | MB_YESNO) != MBID_YES) {
  379.         strcpy(error_message, no_error);
  380.         return 1;
  381.         }
  382.         unlink(outname);
  383.     }
  384.     if (replace) {
  385.         /* modify config.sys */
  386.         if (rename(inname, outname)) {
  387.         sprintf(error_message, "Error renaming %s to %s", inname, outname);
  388.         return 1;
  389.         }
  390.         if (rename(tempname, inname)) {
  391.         sprintf(error_message, "Error renaming %s to %s", tempname, inname);
  392.         return 1;
  393.         }
  394.     }
  395.     else {
  396.         if (rename(tempname, outname)) {
  397.         sprintf(error_message, "Error renaming %s to %s", tempname, outname);
  398.         return 1;
  399.         }
  400.         sprintf(buf, "Changes were saved in %s", outname);
  401.         message_box(buf, MB_MOVEABLE | MB_OK);
  402.     }
  403.     }
  404.     else {
  405.     unlink(tempname);
  406.     }
  407.  
  408.     return 0;
  409. }
  410.  
  411. int
  412. update_fontmap(void)
  413. {
  414. char fontmap[MAXSTR];
  415. char fontmap_os2[MAXSTR];
  416. char fontmap_old[MAXSTR];
  417. char buf[MAXSTR];
  418. FILE *f, *infile;
  419. int backup = 1;
  420.     if ( message_box("OS/2 has some Type 1 fonts of better quality\
  421.  than those distributed with Ghostscript.  Do you want to use them?",
  422.         MB_MOVEABLE | MB_YESNO) != MBID_YES ) {
  423.     return 0;
  424.     }
  425.  
  426.     use_os2_fonts = TRUE;
  427.  
  428.     strcpy(fontmap, destdir);
  429.     strcat(fontmap, BASEDIR);
  430.     strcpy(fontmap_os2, fontmap);
  431.     strcpy(fontmap_old, fontmap);
  432.     strcat(fontmap, "\\Fontmap");
  433.     strcat(fontmap_os2, "\\Fontmap.OS2");
  434.     strcat(fontmap_old, "\\Fontmap.old");
  435.     if ( (f = fopen(fontmap_old, "r")) != (FILE *)NULL)  {
  436.     fclose(f);
  437.     sprintf(buf, "File %s exists.  Overwrite?", fontmap_old);
  438.     if (message_box(buf, MB_MOVEABLE | MB_YESNO) != MBID_YES) {
  439.         backup = 0;
  440.     }
  441.     }
  442.     if (backup) {
  443.     unlink(fontmap_old);
  444.         if (rename(fontmap, fontmap_old)) {
  445.         sprintf(error_message, "Error renaming %s to %s", fontmap, fontmap_old);
  446.         return 1;
  447.     }
  448.     }
  449.  
  450.     infile = fopen(fontmap_os2, "r");
  451.     if (infile == (FILE *)NULL) {
  452.     sprintf(error_message, "Can't open %s for reading", fontmap_os2);
  453.     return 1;
  454.     }
  455.     f = fopen(fontmap, "w");
  456.     if (f == (FILE *)NULL) {
  457.     sprintf(error_message, "Can't create %s for writing", fontmap);
  458.     fclose(infile);
  459.     return 1;
  460.     }
  461.     while (fgets(buf, sizeof(buf), infile))
  462.     fputs(buf, f);
  463.     fclose(infile);
  464.     fclose(f);
  465. }
  466.  
  467. int
  468. update_ini(void)
  469. {
  470. char szIniName[MAXSTR];
  471. PROFILE *prf;
  472. char dest[MAXSTR];
  473. char buf[MAXSTR];
  474.     strcpy(szIniName, bootdrive);
  475.     strcat(szIniName, "\\os2\\gvpm.ini");
  476.     prf = profile_open(szIniName);
  477.     if (prf == (PROFILE *)NULL) {
  478.     sprintf(error_message, "Can't open %s", szIniName);
  479.     return 1;
  480.     }
  481.     strcpy(dest, destdir);
  482.     strcat(dest, BASEDIR);
  483.     strcpy(buf, dest);
  484.     strcat(buf, "\\gsos2.exe");
  485.     profile_write_string(prf, "Options", "GhostscriptEXE", buf);
  486.     strcpy(buf, dest);
  487.     strcat(buf, ";");
  488.     strcat(buf, dest);
  489.     strcat(buf, "\\fonts");
  490.     if (use_os2_fonts) {
  491.         strcat(buf, ";");
  492.     strcat(buf, bootdrive);
  493.     strcat(buf, "\\psfonts");
  494.     }
  495.     profile_write_string(prf, "Options", "GhostscriptInclude", buf);
  496.     profile_write_string(prf, "Options", "GhostscriptVersion", "351");
  497.     profile_write_string(prf, "Options", "Version", GSVIEW_VERSION);
  498.     profile_close(prf);
  499.     return 0;
  500. }
  501.  
  502. int
  503. create_object(void)
  504. {
  505. char buf[MAXSTR];
  506. char setup[MAXSTR];
  507. APIRET rc;
  508.     strcpy(buf, destdir);
  509.     strcat(buf, "\\gsview\\gvpm.exe");
  510.     sprintf(setup, "EXENAME=%s;ASSOCFILTER=*.ps,*.eps,*.pdf", buf);
  511.     rc = !WinCreateObject("WPProgram", "GSview", setup, "<WP_DESKTOP>",
  512.     CO_REPLACEIFEXISTS);
  513.     if (rc) {
  514.     sprintf(error_message, "Couldn't create desktop program object");
  515.     }
  516.     return rc;
  517. }
  518.  
  519.  
  520. int
  521. install(void)
  522. {
  523. char buf[MAXSTR];
  524. int rc;
  525.     rc = init();    /* inspect system */
  526.     
  527.     if (!rc)
  528.         rc = intro();    /* display intro dialog boxes */
  529.  
  530.     if (!rc)
  531.     rc = getdest();    /* get destination directory */
  532.  
  533.     if (!rc) {
  534.     /* copy unzip program for faster loading */
  535.     strcpy(unzipname, destdir);
  536.     strcat(unzipname, "\\gsview");
  537.     mkdir(unzipname, 0);
  538.     strcat(unzipname, "\\");
  539.     strcat(unzipname, UNZIPEXE);
  540.     strcpy(buf, szExePath);
  541.     strcat(buf, UNZIPEXE);
  542.     rc = copyfile(unzipname, buf);
  543.     }
  544.  
  545.     /* unzip GSview and Ghostscript */
  546.     if (!rc) {
  547.     rc = unzip(GSVIEWZIP, destdir);
  548.     }
  549.     if (!rc) {
  550.     /* install EMX if needed */
  551.     sprintf(buf, "%s\\", bootdrive);
  552.     if (!emx)
  553.         rc = unzip(EMXZIP, buf);
  554.     }
  555.     if (!rc)
  556.     rc = unzip(GSINIZIP, destdir);
  557.     if (!rc)
  558.     rc = unzip(GSOS2ZIP, destdir);
  559.     if (!rc) {
  560.     strcpy(buf, destdir);
  561.     strcat(buf, BASEDIR);
  562.     rc = unzip(GSFNTZIP, buf);
  563.     }
  564.  
  565.     /* remove unneeded unzip */
  566.     unlink(unzipname);
  567.  
  568.     if (!rc) {
  569.     rc = update_config();
  570.     }
  571.  
  572.     if (!rc) {
  573.     rc = update_fontmap();
  574.     }
  575.  
  576.     if (!rc) {
  577.     rc = update_ini();
  578.     }
  579.  
  580.     if (!rc) {
  581.     rc = create_object();
  582.     }
  583.  
  584.  
  585.     if (!rc) {
  586.     message_box("Installation successful.\012A GSview program object has been created on the desktop", 
  587.         MB_MOVEABLE | MB_OK);
  588.     }
  589.     return rc;
  590. }
  591.  
  592. int
  593. main(int argc, char *argv[])
  594. {
  595.     HMQ hand_mq;        /* message queue */
  596.     QMSG q_mess;        /* queue message */
  597.     APIRET rc = 0;
  598.  
  599.     hab = WinInitialize(0);    /* Get the Anchor Block */
  600.  
  601.     hand_mq = WinCreateMsgQueue(hab, 0); /* start a queue */
  602.  
  603.     rc = install();
  604.  
  605.     if (rc) {
  606.         char buf[256];
  607.     sprintf(buf, "Installation aborted\012%s", error_message);
  608.     message_box(buf, MB_MOVEABLE | MB_OK);
  609.     }
  610.  
  611.     rc = cleanup();
  612.     WinDestroyMsgQueue(hand_mq);
  613.     WinTerminate(hab);
  614.     return rc;
  615. }
  616.  
  617. /* termination queue thread */
  618. /* This thread waits for termination messages */
  619. /* This thread must NOT call C library functions */
  620. VOID APIENTRY term_thread(ULONG unused)
  621. {
  622.     REQUESTDATA Request;
  623.     ULONG DataLength;
  624.     PVOID DataAddress;
  625.     BYTE ElemPriority;
  626.     unused = unused;    /* to shut up warning */
  627.     while ( !DosReadQueue(term_queue, &Request, &DataLength, &DataAddress, 
  628.             0, DCWW_WAIT, &ElemPriority, (HEV)NULL) ) {
  629.         if (hwnd_dlg)
  630.         WinPostMsg(hwnd_dlg, WM_COMMAND, MPFROM2SHORT(DID_OK, 0), MPFROM2SHORT(CMDSRC_OTHER,FALSE));
  631.         if (DataAddress != (PVOID)NULL)
  632.             DosFreeMem(DataAddress);
  633.     }
  634.     term_tid = 0;
  635. }
  636.  
  637.  
  638. /* General Dialog Box */
  639. MRESULT EXPENTRY GeneralDlgProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
  640. {
  641.   switch(msg) {
  642.     case WM_INITDLG:
  643.         hwnd_dlg = hwnd;
  644.     break;
  645.     case WM_COMMAND:
  646.       switch(SHORT1FROMMP(mp1)) {
  647.         case DID_OK:
  648.       hwnd_dlg = (HWND)NULL;
  649.           WinDismissDlg(hwnd, DID_OK);
  650.           return (MRESULT)TRUE;
  651.     case DID_CANCEL:
  652.       hwnd_dlg = (HWND)NULL;
  653.           WinDismissDlg(hwnd, DID_CANCEL);
  654.           return (MRESULT)TRUE;
  655.       }
  656.       break;
  657.   }
  658.   return WinDefDlgProc(hwnd, msg, mp1, mp2);
  659. }    
  660.  
  661. MRESULT EXPENTRY InputDlgProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
  662. {
  663.   switch(msg) {
  664.     case WM_INITDLG:
  665.     WinSendMsg( WinWindowFromID(hwnd, ID_ANSWER),
  666.             EM_SETTEXTLIMIT, MPFROM2SHORT(MAXSTR, 0), MPFROMLONG(0) );
  667.     WinSetWindowText( WinWindowFromID(hwnd, ID_ANSWER),
  668.           get_string_answer );
  669.         break;
  670.     case WM_COMMAND:
  671.       switch(SHORT1FROMMP(mp1)) {
  672.         case DID_OK:
  673.       WinEnableWindow(WinWindowFromID(hwnd, DID_OK), FALSE);
  674.       WinQueryWindowText(WinWindowFromID(hwnd, ID_ANSWER),
  675.         MAXSTR, get_string_answer);
  676.           WinDismissDlg(hwnd, DID_OK);
  677.           return (MRESULT)TRUE;
  678.     case DID_CANCEL:
  679.           WinDismissDlg(hwnd, DID_CANCEL);
  680.           return (MRESULT)TRUE;
  681.       }
  682.       break;
  683.   }
  684.   return WinDefDlgProc(hwnd, msg, mp1, mp2);
  685. }    
  686.